
import json
import logging
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.contrib.auth.models import AnonymousUser
from user_app.models import User

logger = logging.getLogger(__name__)


class NotificationConsumer(AsyncWebsocketConsumer):
    """通知WebSocket消费者"""
    
    async def connect(self):
        """处理WebSocket连接"""
        self.user_id = self.scope['url_route']['kwargs']['user_id']
        self.user = self.scope['user']
        
        # 验证用户
        if isinstance(self.user, AnonymousUser):
            await self.close()
            return
        
        # 检查用户是否有权限接收通知
        has_permission = await self._check_permission()
        if not has_permission:
            await self.close()
            return
        
        # 加入用户特定的组
        self.group_name = f'user_{self.user_id}_notifications'
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )
        
        await self.accept()
        logger.info(f"WebSocket connected: {self.user.phone} joined {self.group_name}")
    
    async def disconnect(self, close_code):
        """处理WebSocket断开连接"""
        if hasattr(self, 'group_name'):
            await self.channel_layer.group_discard(
                self.group_name,
                self.channel_name
            )
            logger.info(f"WebSocket disconnected: {self.user.phone} left {self.group_name}")
    
    async def receive(self, text_data):
        """接收WebSocket消息"""
        try:
            data = json.loads(text_data)
            message_type = data.get('type')
            
            if message_type == 'ping':
                # 处理心跳消息
                await self.send(text_data=json.dumps({
                    'type': 'pong',
                    'message': 'pong'
                }))
            elif message_type == 'mark_read':
                # 处理标记通知为已读的消息
                await self._handle_mark_read(data)
        except json.JSONDecodeError:
            logger.error("Invalid JSON data received")
        except Exception as e:
            logger.error(f"Error processing WebSocket message: {str(e)}")
    
    async def notification(self, event):
        """处理通知事件"""
        await self.send(text_data=json.dumps(event))
    
    async def _handle_mark_read(self, data):
        """处理标记通知为已读"""
        notification_id = data.get('notification_id')
        if notification_id:
            # 标记通知为已读
            success = await self._mark_notification_read(notification_id)
            
            # 发送确认消息
            await self.send(text_data=json.dumps({
                'type': 'mark_read_response',
                'notification_id': notification_id,
                'success': success
            }))
    
    @database_sync_to_async
    def _check_permission(self):
        """检查用户是否有权限接收通知"""
        return str(self.user.id) == self.user_id
    
    @database_sync_to_async
    def _mark_notification_read(self, notification_id):
        """标记通知为已读"""
        from django.utils import timezone
        from notification_app.models import Notification
        
        try:
            notification = Notification.objects.get(
                id=notification_id,
                recipient=self.user,
                is_read=False
            )
            notification.is_read = True
            notification.read_at = timezone.now()
            notification.save()
            return True
        except Notification.DoesNotExist:
            return False